// controllers/PageController.h
#pragma once
#include <drogon/drogon.h>

using namespace drogon;
using namespace drogon::orm;

class PageController : public drogon::HttpController<PageController>{
public:
    METHOD_LIST_BEGIN
        ADD_METHOD_TO(PageController::home, "/home", Get);
        ADD_METHOD_TO(PageController::problem, "/problem", Get);
        ADD_METHOD_TO(PageController::category, "/category", Get);
        ADD_METHOD_TO(PageController::contest, "/contest", Get);
        ADD_METHOD_TO(PageController::status, "/status", Get);
        ADD_METHOD_TO(PageController::ranklist, "/ranklist", Get);
        ADD_METHOD_TO(PageController::knowledgeGraph, "/knowledge_graph", Get);
        ADD_METHOD_TO(PageController::index, "/index", Get);
        ADD_METHOD_TO(PageController::index, "/", Get);
        ADD_METHOD_TO(PageController::dashboard, "/dashboard", Get);
        ADD_METHOD_TO(PageController::login, "/login", Get);
    METHOD_LIST_END

    void home(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void problem(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void category(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void contest(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void status(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void ranklist(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void knowledgeGraph(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void index(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void dashboard(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
    void login(const HttpRequestPtr& req, std::function<void(const HttpResponsePtr&)>&& callback);
private:
    // 获取当前登录用户ID
    std::string getCurrentUserId(const HttpRequestPtr& req) {
        auto user_id_attr = req->getAttributes()->get<std::string>("user_id");
        if (user_id_attr.size()) {
            return std::any_cast<std::string>(user_id_attr);
        }
        return "";  
    }
    
    // 检查用户是否已认证
    bool isAuthenticated(const HttpRequestPtr& req) {
        return !getCurrentUserId(req).empty();
    }
    
    // 设置视图的公共数据
    void setCommonViewData(const HttpRequestPtr& req, HttpViewData& data) {
        // 系统配置变量（这些应该从配置文件中读取）
        
        // 用户相关信息
        std::string user_id = getCurrentUserId(req);
        data.insert("user_id", user_id);
        
        // 如果用户已登录，查询用户权限信息
        if (!user_id.empty()) {
            setUserPermissionData(req, data, user_id);
        } else {
            // 未登录用户的默认权限
            data.insert("is_administrator", false);
            data.insert("is_contest_creator", false);
            data.insert("is_problem_editor", false);
            data.insert("admin_notification_num", 0);
        }
        
    }
    
    // 设置用户权限数据
    void setUserPermissionData(const HttpRequestPtr& req, HttpViewData& data, const std::string& user_id) {
        auto dbClient = app().getDbClient();
        
        // 异步查询用户权限信息
        dbClient->execSqlAsync(
            "SELECT is_administrator, is_contest_creator, is_problem_editor FROM users WHERE user_id = ?",
            [&data](const Result& result) {
                if (!result.empty()) {
                    auto row = result[0];
                    data.insert("is_administrator", row["is_administrator"].as<bool>());
                    data.insert("is_contest_creator", row["is_contest_creator"].as<bool>());
                    data.insert("is_problem_editor", row["is_problem_editor"].as<bool>());
                    
                    // 如果是管理员，查询通知数量
                    if (row["is_administrator"].as<bool>()) {
                        // 这里可以查询管理员通知数量
                        data.insert("admin_notification_num", 0); // 暂时设为0
                    } else {
                        data.insert("admin_notification_num", 0);
                    }
                }
            },
            [](const DrogonDbException& e) {
                LOG_ERROR << "Database error when querying user permissions: " << e.base().what();
            },
            user_id
        );
    }
};